package org.apli.haiam.admin.jsf.managed;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.ResourceBundle;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.model.DataModel;
import javax.faces.model.SelectItem;
import org.apli.haiam.admin.entidades.UsuarioAdmin;
import org.apli.haiam.ejb.entidades.AdmTipoConsulta;
import org.apli.haiam.ejb.entidades.AdmUsuario;
import org.apli.haiam.ejb.entidades.CexEspecialidad;
import org.apli.haiam.ejb.entidades.CexHorariosDia;
import org.apli.haiam.ejb.entidades.CexPreparacion;
import org.apli.jsf.managed.JsfBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Clase backing Bean que administra la entidad CexPreparacion.
 * <p>
 * <H6>Soporte:HAIAM
 * <I>david_s_1086@hotmail.com,david.carranza@haiam.gob.ec</I></H6>
 *
 * @author david Carranza
 * @version 1.0 30/07/2014
 */
@ManagedBean
@ViewScoped
public class JsfPreparacionModificacion extends JsfBean<CexPreparacion> {

    final Logger log = LoggerFactory.getLogger(JsfPreparacionModificacion.class);
    private CexEspecialidad subEspecialidad;
    private CexHorariosDia horarioDia;
    private Integer edad;
    private UsuarioAdmin user;
    private AdmUsuario admUsuario;
    private Date fechaPreparacion;
    private CexPreparacion ultimoPeso;
    private CexPreparacion ultimoRenovacion;
    private boolean activarPeso;
    private boolean activarRenovacion;
    private AdmTipoConsulta admTipoConsulta;
    private String observacion;

    /**
     * Constructor por defecto.
     */
    public JsfPreparacionModificacion() {
    }

    /**
     * Inicializa los datos miembros.
     */
    @Override
    protected void inicializar() {
        //setSwGrabar(false);
        object = new CexPreparacion();
        object.setCprPeso(BigDecimal.ZERO);
        object.setCprTalla(BigDecimal.ZERO);
        subEspecialidad = new CexEspecialidad();
        horarioDia = new CexHorariosDia();
        user = (UsuarioAdmin) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user");
        admUsuario = user.getUser();
        edad = 0;
        ultimoPeso = new CexPreparacion();
        ultimoRenovacion = new CexPreparacion();
        activarPeso = false;
        activarRenovacion = false;
        observacion = "";
        try {
            fechaPreparacion = admin.getFechaDb();
            if (user.getUser().getAdmEmpleado().getAdmDepartamento().getIdDepartamento().equals(4)) {
                admTipoConsulta = (AdmTipoConsulta) adminObject.buscar(AdmTipoConsulta.class, "atcId", 2);
            } else if (user.getUser().getAdmEmpleado().getAdmDepartamento().getIdDepartamento().equals(2)) {
                admTipoConsulta = (AdmTipoConsulta) adminObject.buscar(AdmTipoConsulta.class, "atcId", 1);
            } else if (user.getUser().getAdmEmpleado().getAdmDepartamento().getIdDepartamento().equals(1) || !user.getUser().getAdmEmpleado().getAdmDepartamento().getIdDepartamento().equals(3)) {
                admTipoConsulta = (AdmTipoConsulta) adminObject.buscar(AdmTipoConsulta.class, "atcId", 1);
            }
        } catch (Exception e) {
            log.error("obtener Fecha() {} ", e.getMessage());
        }
        cargarLista();

    }

    /**
     * Graba el registro asociado al objeto que se administra en la página.
     *
     * @return null, se mantiene en la página invocada.
     */
    @Override
    public String grabarAction() {
        FacesContext context = FacesContext.getCurrentInstance();
        if (object.getCexAgenda().getCexHistoriaClinica() != null) {
            if (object.getCprId() != null) {
                try {
                    object.setCprObservaciones(object.getCprObservaciones().concat(" ").concat(observacion));
                    //modifica la historia clinica con relacion a los años del paciente adminObject
                    admin.modificar(object.getCexAgenda().getCexHistoriaClinica(), (UsuarioAdmin) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("user"));
                    FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(bundle.getString("msg.actualizar")));
                } catch (Exception e) {
                    log.error("grabarAction() {} ", e.getMessage());
                    FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), e.getMessage()));
                }
            } else {
                FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "No se grabo el registro", "No se grabo el registro"));
            }
        } else {
            FacesContext.getCurrentInstance().addMessage(findComponent(context.getViewRoot(), "formDatos").getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, "Debe seleccionar un paciente", "Debe seleccionar un paciente"));
        }

        return null;
    }

    /**
     * Implementa el comportamiento para seleccionar un elemento en una lista de
     * la página.
     *
     * @param item
     * @return null, se mantiene en la página invocada.
     */
    public String seleccionarActionPreparacion(CexPreparacion item) {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "()";
        FacesContext context = FacesContext.getCurrentInstance();
        List<CexPreparacion> listatem;
        //inicializar();
        try {
            ultimoPeso = null;
            ultimoRenovacion = null;
            object = item;
            observacion = object.getCprObservaciones().trim();
            object.setCprObservaciones("");
            //Saca el ultimo peso y a ultima renovacion de la preparacio de acuerdo a la historia clinica
            listatem = admin.listarOrdenada(object.getClass(), "cexAgenda.cexHistoriaClinica", object.getCexAgenda().getCexHistoriaClinica(), "cprFecha", false);
            for (CexPreparacion objCex : listatem) {
                //Ultimo peso
                if (!objCex.getCprPeso().equals(new BigDecimal("0.00"))) {
                    ultimoPeso = objCex;
                    break;
                }
            }

            for (CexPreparacion objCexa : listatem) {
                //Ultima renovacion
                if (objCexa.getCprRenova()) {
                    ultimoRenovacion = objCexa;
                    break;
                }
            }

        } catch (Exception e) {
            log.error("{}: {} ", nombreMetodo, e);
        }
        return null;
    }

    /**
     * Carga la lista de objetos en una lista de la página.
     */
    @Override
    public void cargarLista() {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "()";
        if (admin == null) {
            lista = null;
            return;
        }
        try {
            ultimoPeso = null;
            ultimoRenovacion = null;
            activarPeso = false;
            activarRenovacion = false;
            lista = new ArrayList<>();
            if (user.getUser().getAdmEmpleado().getAdmDepartamento().getIdDepartamento().equals(4)) {
                lista = admin.listarOrdenada(CexPreparacion.class, "cexAgenda.cagFecha", fechaPreparacion, "cexAgenda.cexHorariosDia.cexHorario.admTipoConsulta", admTipoConsulta, "cprEstado", 2, "cexAgenda.cagHora", true);
                //habilitar para el ingreso de peso en el caso de fisiatria
                activarPeso = true;
            } else {
                lista = admin.listarOrdenada(CexPreparacion.class, "cexAgenda.cagFecha", fechaPreparacion, "cprEstado", 2, "cexAgenda.cagHora", true);
            }
        } catch (Exception e) {
            log.error("{}: {} ", nombreMetodo, e);
        }
    }

    /**
     * Funcion que divide dos numero BigDecimales en el caso de que el resultado
     * sea mas extenso de lo que este puede abarcar en la expecion lo divide
     * como double
     *
     * @param A
     * @param B
     * @return BigDecimal,
     */
    public static BigDecimal divisionControlada(BigDecimal A, BigDecimal B) {
        try {
            return A.divide(B);
        } catch (Exception e) {
            return new BigDecimal(A.doubleValue() / B.doubleValue());
        }
    }

    /**
     * Calcula el indice de masa corporal.
     */
    public void calcularImc() {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "()";
        if (admin == null) {
            return;
        }
        try {
            if (!object.getCprPeso().equals(BigDecimal.ZERO) && !object.getCprTalla().equals(BigDecimal.ZERO)) {
                BigDecimal elevado = object.getCprTalla().pow(2);
                BigDecimal res = divisionControlada(object.getCprPeso(), elevado).setScale(2, RoundingMode.UP);
                object.setCprImc(res);
                if (object.getCprImc().compareTo(new BigDecimal(16)) == -1) {
                    object.setCprObservaciones("INDICE DE MASA CORPORAL EQUIVALENTE A INFRAPESO (DELGADEZ SEVERA) ");
                } else {
                    if ((object.getCprImc().compareTo(new BigDecimal(16)) == 1 || object.getCprImc().compareTo(new BigDecimal(16)) == 0) && object.getCprImc().compareTo(new BigDecimal(17)) == -1) {
                        object.setCprObservaciones("INDICE DE MASA CORPORAL EQUIVALENTE A INFRAPESO (DELGADEZ MODERADA)");
                    } else {
                        if ((object.getCprImc().compareTo(new BigDecimal(17)) == 1 || object.getCprImc().compareTo(new BigDecimal(17)) == 0) && object.getCprImc().compareTo(new BigDecimal(18.50)) == -1) {
                            object.setCprObservaciones("INDICE DE MASA CORPORAL EQUIVALENTE A INFRAPESO (DELGADEZ ACEPTABLE)");
                        } else {
                            if ((object.getCprImc().compareTo(new BigDecimal(18.50)) == 1 || object.getCprImc().compareTo(new BigDecimal(18.50)) == 0) && object.getCprImc().compareTo(new BigDecimal(25)) == -1) {
                                object.setCprObservaciones("INDICE DE MASA CORPORAL EQUIVALENTE A NORMAL");
                            } else {
                                if ((object.getCprImc().compareTo(new BigDecimal(25)) == 1 || object.getCprImc().compareTo(new BigDecimal(25)) == 0) && object.getCprImc().compareTo(new BigDecimal(30)) == -1) {
                                    object.setCprObservaciones("INDICE DE MASA CORPORAL EQUIVALENTE A SOBREPESO");
                                } else {
                                    if ((object.getCprImc().compareTo(new BigDecimal(30)) == 1 || object.getCprImc().compareTo(new BigDecimal(30)) == 0) && object.getCprImc().compareTo(new BigDecimal(35)) == -1) {
                                        object.setCprObservaciones("INDICE DE MASA CORPORAL EQUIVALENTE A OBESO DE TIPO I");
                                    } else {
                                        if ((object.getCprImc().compareTo(new BigDecimal(35)) == 1 || object.getCprImc().compareTo(new BigDecimal(35)) == 0) && object.getCprImc().compareTo(new BigDecimal(40)) == -1) {
                                            object.setCprObservaciones("INDICE DE MASA CORPORAL EQUIVALENTE A OBESO DE TIPO II");
                                        } else {
                                            if (object.getCprImc().compareTo(new BigDecimal(40)) == 1 || object.getCprImc().compareTo(new BigDecimal(40)) == 0) {
                                                object.setCprObservaciones("INDICE DE MASA CORPORAL EQUIVALENTE A OBESO DE TIPO III");
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            } else {
                object.setCprImc(BigDecimal.ZERO);
                object.setCprObservaciones("NO SE PUDO SACAR IMC DEBIDO A VALORES EN CERO");

            }

        } catch (Exception e) {
            log.error("{}: {} ", nombreMetodo, e);
        }
    }

    /**
     * Calcula rangos de presion arterial pasado los 2 años de edad.
     */
    public void calcularPresionArterial() {
////////////////        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "()";
////////////////        if (admin == null) {
////////////////            return;
////////////////        }
////////////////        try {
////////////////            if (object.getPreTensioMax() > 0 && object.getPreTensioMin() > 0) {
////////////////                if (object.getPreTensioMax() < 50 && object.getPreTensioMin() < 35) {
////////////////                    object.setPreObservaciones(object.getPreObservaciones().concat(";").concat("PRESION ARTERIAL EQUIVALENTE A MUERTE"));
////////////////                    return;
////////////////                }
////////////////                if ((object.getPreTensioMax() >= 50 && object.getPreTensioMax() < 90) && (object.getPreTensioMin() >= 30 && object.getPreTensioMin() < 60)) {
////////////////                    object.setPreObservaciones(object.getPreObservaciones().concat(";").concat("HIPERTENSIÓN PRESION ARTERIAL BAJA"));
////////////////                    return;
////////////////                }
////////////////                if ((object.getPreTensioMax() >= 90 && object.getPreTensioMax() < 110) && (object.getPreTensioMin() >= 60 && object.getPreTensioMin() < 70)) {
////////////////                    object.setPreObservaciones(object.getPreObservaciones().concat(";").concat("HIPERTENSIÓN PRESION ARTERIAL NORMAL BAJA"));
////////////////                    return;
////////////////                }
////////////////                if ((object.getPreTensioMax() >= 110 && object.getPreTensioMax() < 120) && (object.getPreTensioMin() >= 70 && object.getPreTensioMin() < 80)) {
////////////////                    object.setPreObservaciones(object.getPreObservaciones().concat(";").concat("HIPERTENSIÓN PRESION ARTERIAL NORMAL"));
////////////////                    return;
////////////////                }
////////////////                if ((object.getPreTensioMax() >= 120 && object.getPreTensioMax() < 140) && (object.getPreTensioMin() >= 80 && object.getPreTensioMin() < 90)) {
////////////////                    object.setPreObservaciones(object.getPreObservaciones().concat(";").concat("HIPERTENSIÓN PRESION ARTERIAL NORMAL ALTA"));
////////////////                    return;
////////////////                }
////////////////                if ((object.getPreTensioMax() >= 140 && object.getPreTensioMax() < 160) && (object.getPreTensioMin() >= 90 && object.getPreTensioMin() < 100)) {
////////////////                    object.setPreObservaciones(object.getPreObservaciones().concat(";").concat("HIPERTENSIÓN PRESION ARTERIAL ALTA (BAJA ETAPA 1)"));
////////////////                    return;
////////////////                }
////////////////                if ((object.getPreTensioMax() >= 160 && object.getPreTensioMax() < 180) && (object.getPreTensioMin() >= 100 && object.getPreTensioMin() < 110)) {
////////////////                    object.setPreObservaciones(object.getPreObservaciones().concat(";").concat("HIPERTENSIÓN PRESION ARTERIAL ALTA (MODERADA ETAPA 2)"));
////////////////                    return;
////////////////                }
////////////////                if ((object.getPreTensioMax() >= 180 && object.getPreTensioMax() < 210) && (object.getPreTensioMin() >= 110 && object.getPreTensioMin() < 125)) {
////////////////                    object.setPreObservaciones(object.getPreObservaciones().concat(";").concat("HIPERTENSIÓN PRESION ARTERIAL ALTA (SEVERA ETAPA 3)"));
////////////////                    return;
////////////////                }
////////////////                if ((object.getPreTensioMax() >= 210 && object.getPreTensioMax() < 230) && (object.getPreTensioMin() >= 125 && object.getPreTensioMin() < 140)) {
////////////////                    object.setPreObservaciones(object.getPreObservaciones().concat(";").concat("HIPERTENSIÓN PRESION ARTERIAL ALTA (MUY SEVERA ETAPA 4)"));
////////////////                }
////////////////            } else {
////////////////                object.setPreObservaciones(object.getPreObservaciones().concat(";").concat("NO SE PUDO CALCULAR PRESIÓN ARTERIAL DEBIDO A VALORES EN CERO"));
////////////////            }
////////////////
////////////////        } catch (Exception e) {
////////////////            log.error("{}: {} ", nombreMetodo, e);
////////////////        }
    }

    /**
     * Obtiene una lista de objetos de tipo SelectedItem.
     *
     * @return la lista
     */
    @Override
    public List<SelectItem> getSelectedItem() {
//        try {
//            List<CexPreparacion> datos = admin.listarOrdenada(object.getClass(), "nombre", true);
//            List<SelectItem> items = new ArrayList<SelectItem>();
//            for (CexPreparacion obj : datos) {
//                items.add(new SelectItem(obj.getIdPreparacion()));
//            }
//            return items;
//        } catch (Exception e) {
//            log.error("getSelectedItem() {} ", e.getMessage());
//        }
        return null;
    }

    /**
     * Obtiene una lista de objetos de tipo SelectedItem.
     *
     */
    public void limpiarObjeto() {
        try {
            if (activarPeso && activarRenovacion) {
                activarPeso = false;
                activarRenovacion = false;
            }
        } catch (Exception e) {
            log.error("limpiarObjeto() {} ", e.getMessage());
        }
    }

    public List<SelectItem> getSelectedItemMedico() {
////////////////        try {
////////////////            Date c11 = new Date();
////////////////            Calendar c1 = Calendar.getInstance();
////////////////            c1.setTime(c11);
////////////////            Integer dia = c1.get(Calendar.DAY_OF_WEEK);
////////////////            // lista de registro de la tabla especialidad_medico
////////////////            List<CexHorariosDia> listaHorarioDia = adminObject.listar(CexHorariosDia.class, "cexHorario.cexEspecialidadMedico.cexEspecialidad", subEspecialidad, "cexDia.diaId", dia);
////////////////            List<SelectItem> items = new ArrayList<>();
////////////////            for (CexHorariosDia obj : listaHorarioDia) {
////////////////                if ((obj.getHodHoraInicioAm() != null || obj.getHodHoraFinAm() != null) || (obj.getHodHoraInicioPm() != null || obj.getHodHoraFinPm() != null)) {
////////////////                    items.add(new SelectItem(obj, obj.getCexHorario().getCexEspecialidadMedico().getCexMedico().getMedNombreFull()));
////////////////                }
////////////////
////////////////            }
////////////////            return items;
////////////////        } catch (Exception e) {
////////////////            log.error("getSelectedItemMedico() {} ", e.getMessage());
////////////////        }
        return null;
    }

    @Override
    public DataModel<CexPreparacion> getDataModel() {
        return null;
    }

    public CexEspecialidad getSubEspecialidad() {
        return subEspecialidad;
    }

    public void setSubEspecialidad(CexEspecialidad subEspecialidad) {
        this.subEspecialidad = subEspecialidad;
    }

    public CexHorariosDia getHorarioDia() {
        return horarioDia;
    }

    public void setHorarioDia(CexHorariosDia horarioDia) {
        this.horarioDia = horarioDia;
    }

    public Integer getEdad() {
        return edad;
    }

    public void setEdad(Integer edad) {
        this.edad = edad;
    }

    public Date getFechaPreparacion() {
        return fechaPreparacion;
    }

    public void setFechaPreparacion(Date fechaPreparacion) {
        this.fechaPreparacion = fechaPreparacion;
    }

    public CexPreparacion getUltimoPeso() {
        return ultimoPeso;
    }

    public void setUltimoPeso(CexPreparacion ultimoPeso) {
        this.ultimoPeso = ultimoPeso;
    }

    public CexPreparacion getUltimoRenovacion() {
        return ultimoRenovacion;
    }

    public void setUltimoRenovacion(CexPreparacion ultimoRenovacion) {
        this.ultimoRenovacion = ultimoRenovacion;
    }

    public boolean isActivarPeso() {
        return activarPeso;
    }

    public void setActivarPeso(boolean activarPeso) {
        this.activarPeso = activarPeso;
    }

    public boolean isActivarRenovacion() {
        return activarRenovacion;
    }

    public void setActivarRenovacion(boolean activarRenovacion) {
        this.activarRenovacion = activarRenovacion;
    }

    @Override
    protected ResourceBundle getProperties() {
        return ResourceBundle.getBundle("aplicacion");
    }

    public AdmUsuario getAdmUsuario() {
        return admUsuario;
    }

    public void setAdmUsuario(AdmUsuario admUsuario) {
        this.admUsuario = admUsuario;
    }

}
